package com.gitee.qdbp.general.common.biz.sms.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitee.qdbp.able.beans.Duration.Second;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.error.GeneralErrorCode;
import com.gitee.qdbp.tools.cache.ICacheService;
import com.gitee.qdbp.tools.utils.Config;

/**
 * 短信基础业务默认实现类
 *
 * @author zhaohuihua
 * @version 160831
 */
public class DefSmsBusiness implements ISmsBaseBusiness, Config.Aware, ICacheService.Aware {

    private static final Logger log = LoggerFactory.getLogger(DefSmsBusiness.class);

    private Config config;

    private LastTimeCache cache;

    public DefSmsBusiness() {
        this.config = new Config();
        this.cache = new LastTimeCache();
    }

    public void check(String phone, String type) throws ServiceException {
        // 间隔时间检查
        checkTimeInterval(phone, type);
        // 黑白名单检查
        // 其他检查
        // ...
    }

    public int getCacheTime(String type) throws ServiceException {
        Integer time = config.getInteger("time.cache." + type, false);
        if (time == null) {
            time = config.getInteger("time.cache", false);
        }
        String msg = "Failed to get Short Message validate code cache time.";
        if (time == null || time.intValue() <= 0) {
            log.error(msg + " config not found. type:{}.", type);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_TOO_OFTEN);
        }
        if (time.intValue() <= 0) {
            log.error(msg + " config value must greater than 0. type:{}.", type);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_TOO_OFTEN);
        }

        return time;
    }

    private void checkTimeInterval(String phone, String type) throws ServiceException {
        Integer interval = getTimeInterval(phone, type);
        if (interval == null || interval.intValue() <= 0) {
            return; // 不限制
        }

        checkTimeInterval(phone, type, interval);
    }

    /**
     * 检查间隔时间, 单位:秒
     * 
     * @param phone 手机号码
     * @param type 短信类型
     * @param interval 间隔时间, 单位:秒
     * @throws ServiceException
     */
    protected void checkTimeInterval(String phone, String type, int interval) throws ServiceException {

        Long prev = cache.get(phone, type);
        Long curr = System.currentTimeMillis();
        if (prev != null && curr - prev <= interval * 1000) {
            log.error("Send Short Message too often. phone:{}, type:{}.", phone, type);
            throw new ServiceException(GeneralErrorCode.SMS_SEND_TOO_OFTEN);
        }
        cache.set(phone, type, curr);
    }

    /**
     * 获取间隔时间, 单位:秒
     * 
     * @param phone 手机号码
     * @param type 短信类型
     * @return 间隔时间
     * @throws ServiceException
     */
    protected Integer getTimeInterval(String phone, String type) throws ServiceException {
        Integer interval = config.getInteger("time.interval." + type, false);
        if (interval == null) {
            interval = config.getInteger("time.interval", false);
        }
        return interval;
    }

    public void setConfig(Config config) {
        this.config = config;
        Integer time = config.getInteger("time.cache");
        if (time != null) {
            this.cache.setExpiredTime(new Second(time));
        }
    }

    public void setCacheService(ICacheService cache) {
        this.cache.setCache(cache);
    }
}
